package com.dant.components.lists
{
	import flash.display.DisplayObject;
	
	import mx.collections.XMLListCollection;
	import mx.containers.Box;
	import mx.containers.BoxDirection;
	import mx.controls.LinkButton;
	import mx.core.ClassFactory;
	import mx.core.IFactory;
	import mx.events.ItemClickEvent;


    [Style(name="horizontalGap", type="Number", inherit="no")]
    [Style(name="verticalGap", type="String", inherit="no")]
    [Style(name="selectedPathVerticalAlign", type="String", inherit="no")]
    [Style(name="verticalGap", type="Number", inherit="no")]
    [Style(name="horizontalGap", type="Number", inherit="no")]
    [Style(name="verticalGap", type="Number", inherit="no")]

    [Style(name="itemHighlightSkin", type="Class", inherit="no")]

    [Style(name="highlightRadius", type="Number", inherit="no")]
    [Style(name="highlightColors", type="Array", inherit="no")]

    [Event(name="itemClick", type="mx.events.ItemClickEvent")] 
    [DefaultProperty("dataProvider")]
	public class HierarchicalList extends Box
	{
		/**
		* @private
		*
		*/
		private var _buttonScrollWidth : Number;
		private var buttonScrollWidthChanged : Boolean;

		/**
		* @private
		*
		*/
		private var _dataProvider : XML;
		private var dataProviderChanged : Boolean;

        /**
        * @private
        *
        */
        private var directionChanged : Boolean = true;


		/**
		* @private
		*
		*/
		private var _itemRenderer : IFactory = new ClassFactory(LinkButton);
		private var itemRendererChanged : Boolean = true;

		/**
		 * 
		 */		
		private var listContainer:SmoothScrollingList;
		
        /**
         * 
         */		
        private var _labelField:String;
        private var labelFieldChanged:Boolean;
        
        
        /**
         * 
         */        
        protected var selectedPathDataProvider:XMLListCollection;

        /**
         * 
         */        
        private var _selectedPathItemRenderer:IFactory;
        private var selectedPathItemRendererChanged:Boolean;

		/**
		 * 
		 */
		private var selectedPathContainer:SmoothScrollingList;


        /**
        * @private
        *
        */
        private var _scrollSpeed : Number;
        private var scrollSpeedChanged : Boolean;

        /**
        * @private
        *
        */
        private var _startScrollEvent: String;
        private var startScrollEventChanged : Boolean;

        /**
        * @private
        *
        */
        private var _stopScrollEvent : String;
        private var stopScrollEventChanged : Boolean;

		[Bindable]
		/**
		*
		*
		*/
		public function set buttonScrollWidth(value:Number):void
		{
		    if ( _buttonScrollWidth != value )
		    {
		        _buttonScrollWidth = value;
		        buttonScrollWidthChanged = true;
		        invalidateProperties();
		    }
		}
		
		public function get buttonScrollWidth():Number
		{
		    return _buttonScrollWidth;
		}

        [Bindable]
        /**
        *
        *
        */
        override public function set direction(value:String):void
        {
            super.direction = value;
            directionChanged = true;
            invalidateProperties();
        }


		[Bindable]
		/**
		*
		*
		*/
		public function set itemRenderer(value:IFactory):void
		{
		    if ( _itemRenderer != value )
		    {
		        _itemRenderer = value;
		        itemRendererChanged = true;
		        invalidateProperties();
		    }
		}
		
		public function get itemRenderer():IFactory
		{
		    return _itemRenderer;
		}

		[Bindable]
		/**
		*
		*
		*/
		public function set selectedPathItemRenderer(value:IFactory):void
		{
		    if ( _selectedPathItemRenderer != value )
		    {
		        _selectedPathItemRenderer = value;
		        selectedPathItemRendererChanged = true;
		        invalidateProperties();
		    }
		}
		
		public function get selectedPathItemRenderer():IFactory
		{
		    return _selectedPathItemRenderer;
		}


		[Bindable]
		/**
		*
		*
		*/
		public function set dataProvider(value:XML):void
		{
			if ( _dataProvider != value )
			{
				_dataProvider = value;
				dataProviderChanged = true;
				invalidateProperties();
			}
		}

		public function get dataProvider():XML
		{
			return _dataProvider;
		}

        [Bindable]
		/**
		*
		*
		*/
		public function set labelField(value:String):void
		{
			if ( _labelField != value )
			{
				_labelField = value;
				labelFieldChanged = true;
				invalidateProperties();
			}
		}

		public function get labelField():String
		{
			return _labelField;
		}

        [Bindable]
        /**
        *
        *
        */
        public function set scrollSpeed(value:Number):void
        {
            if ( _scrollSpeed != value )
            {
                _scrollSpeed = value;
                scrollSpeedChanged = true;
                invalidateProperties();
            }
        }
        
        public function get scrollSpeed():Number
        {
            return _scrollSpeed;
        }

        [Bindable]
		/**
		*
		*
		*/
		public function set startScrollEvent(value:String):void
		{
			if ( _startScrollEvent != value )
			{
				_startScrollEvent = value;
				startScrollEventChanged = true;
				invalidateProperties();
			}
		}

		public function get startScrollEvent():String
		{
			return _startScrollEvent;
		}

        [Bindable]
		/**
		*
		*
		*/
		public function set stopScrollEvent(value:String):void
		{
			if ( _stopScrollEvent != value )
			{
				_stopScrollEvent = value;
				stopScrollEventChanged = true;
				invalidateProperties();
			}
		}

		public function get stopScrollEvent():String
		{
			return _stopScrollEvent;
		}


		public function HierarchicalList()
		{
			super();
		}

        override protected function createChildren():void
        {
        	super.createChildren();
        	
        	direction = BoxDirection.VERTICAL;

        	listContainer = new SmoothScrollingList();
        	listContainer.percentHeight = 100;
        	listContainer.percentWidth = 100;
        	listContainer.addEventListener(ItemClickEvent.ITEM_CLICK, 
        	                   listContainer_itemClickHandler, false, 0, true);

//        	selectedPathContainer.direction = BoxDirection.VERTICAL;

            selectedPathContainer = new SmoothScrollingList();
            selectedPathContainer.percentWidth = 100;
//            selectedPathContainer.percentHeight = 30;
            selectedPathContainer.addEventListener(ItemClickEvent.ITEM_CLICK,
                                    selectedPath_itemClickHandler,false,0,true);

        	addChild(selectedPathContainer);
        	addChild(listContainer);
        }

		override protected function commitProperties():void
		{
			super.commitProperties();
			if ( directionChanged )
			{
				listContainer.direction = direction;
				selectedPathContainer.direction = direction;
				directionChanged = false;
			}
			
			if ( dataProviderChanged )
			{
				listContainer.dataProvider = dataProvider;
				dataProviderChanged = false;
			}
			if ( labelFieldChanged )
			{
				listContainer.labelField = labelField;
				selectedPathContainer.labelField = labelField;
				labelFieldChanged = false;
			}
			if ( itemRendererChanged )
			{
				listContainer.itemRenderer = itemRenderer;
				itemRendererChanged = false;
			}
			if ( buttonScrollWidthChanged )
			{
				listContainer.buttonWidth = buttonScrollWidth;
				selectedPathContainer.buttonWidth = buttonScrollWidth;
				buttonScrollWidthChanged = false;
			}
			if ( startScrollEventChanged )
			{
				listContainer.startScrollingEvent = startScrollEvent;
				selectedPathContainer.startScrollingEvent = startScrollEvent;
				startScrollEventChanged = false;
			}
			if ( stopScrollEventChanged )
			{
				listContainer.stopScrollingEvent = stopScrollEvent;
				selectedPathContainer.stopScrollingEvent = stopScrollEvent;
				stopScrollEventChanged = false;
			}
			if ( selectedPathItemRendererChanged )
			{
				selectedPathContainer.itemRenderer = selectedPathItemRenderer;
				selectedPathItemRendererChanged = false;
			}
		}

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
        	super.updateDisplayList(unscaledWidth,unscaledHeight);
        	invalidateSize();
        }
        
        override protected function measure():void
        {
        	super.measure();
        	
        	var calculatedWidth:int = 0;
        	var calculatedHeight:int = 0;
        	var verticalGap:int = getStyle("verticalGap");
        	var horizontalGap:int = getStyle("horizontalGap");
        	var item:DisplayObject;
        	
        	if ( direction == BoxDirection.VERTICAL )
        	{
        		calculatedWidth = Math.max(listContainer.width,selectedPathContainer.width) + 10;
        		calculatedHeight = listContainer.height + verticalGap + selectedPathContainer.height;
        	}
        	else if ( direction == BoxDirection.HORIZONTAL )
        	{
        		calculatedWidth = listContainer.width + horizontalGap + selectedPathContainer.width;
        		calculatedHeight = Math.max(selectedPathContainer.height, listContainer.height);
        	}
        	
        	measuredHeight = calculatedHeight;
        	measuredWidth = calculatedWidth;
        }

        protected function addItemToSelectedPath(item:XML):void
        {
            if (!selectedPathDataProvider)
            {
                selectedPathDataProvider = new XMLListCollection();
                selectedPathContainer.dataProvider = selectedPathDataProvider;
            }

            selectedPathDataProvider.addItem(item);
        }

        public function getSelectedPath():XMLListCollection
        {
            return (selectedPathDataProvider);
         }

        protected function goBackInSelection(item:XML, 
	                                selectedPathDataProvider:XMLListCollection, 
	                                index:int = -1):void
        {
        	var numItems:int = selectedPathDataProvider ? selectedPathDataProvider.length:0;

        	for (var i:int = numItems-1; (i>=index)&&(i>=0); i--)
        	{
        		selectedPathDataProvider.removeItemAt(i);
        	}

            var lastItem:XML = ((selectedPathDataProvider)&&
                               (selectedPathDataProvider.length>0)) ? 
                               selectedPathDataProvider[selectedPathDataProvider.length-1]:null;
        	listContainer.dataProvider = lastItem ? lastItem.children():this.dataProvider;
        }
        
        public function resetSelectedPath():void
        {
        	if (selectedPathDataProvider && selectedPathDataProvider.length>0)
        	{
                goBackInSelection(XML(selectedPathDataProvider.getItemAt(0)),selectedPathDataProvider,0);
            }
        }

        private function selectedPath_itemClickHandler(event:ItemClickEvent):void
        {
        	var item:Object = event.item;
        	goBackInSelection(XML(item), selectedPathDataProvider, event.index);
        }

        protected function listContainer_itemClickHandler(event:ItemClickEvent):void
        {
/*         	
        	var animateProperty:AnimateProperty = new AnimateProperty();
        	animateProperty.property = "verticalScrollPosition";
        	animateProperty.fromValue = verticalScrollPosition;
        	animateProperty.toValue = 0;
        	animateProperty.duration = 1000;
        	animateProperty.target = this;
        	animateProperty.play([this]);
 */
        	var itemData:Object = event.item;

            addItemToSelectedPath(XML(itemData).copy());

        	// sets the hierarchical dataProvider
        	var children:XMLList = XML(itemData).children();

        	listContainer.dataProvider = children;
        	
        }
	}
}